package com.gzdict.common.net

import com.alibaba.fastjson.JSON
import com.drake.net.NetConfig
import com.drake.net.convert.JSONConvert
import com.drake.net.convert.NetConverter
import com.drake.net.exception.ConvertException
import com.drake.net.exception.RequestParamsException
import com.drake.net.exception.ResponseException
import com.drake.net.exception.ServerResponseException
import com.gzdict.common.exception.NetConvertException
import okhttp3.Response
import org.json.JSONException
import org.json.JSONObject
import java.lang.reflect.Type

class FastJsonConverter(private val code:String? = "code",
                        private val message:String? = "message",
                        private val data:String? = "data",
                        private val success: String? = "0") : NetConverter {

    override fun <R> onConvert(succeed: Type, response: Response): R? {
        try {
            return NetConverter.onConvert<R>(succeed, response)
        } catch (e: ConvertException) {
            val code = response.code
            val bodyString = response.body?.string() ?: return null

            when {
                code in 200..299 -> { // 请求成功
                    return try {
                        val json = JSONObject(bodyString) // 获取JSON中后端定义的错误码和错误信息
                        val srvCode = json.getString(this.code)
                        val result = json.optString(data)
                        if (srvCode == success) { // 对比后端自定义错误码
                            result.parseBody<R>(succeed)
                        } else { // 错误码匹配失败, 开始写入错误异常
                            val errorMessage = json.optString(message, NetConfig.app.getString(com.drake.net.R.string.no_error_message))
                            throw NetConvertException(response,srvCode,errorMessage,result)
                        }
                    } catch (e: JSONException) { // 固定格式JSON分析失败直接解析JSON
                        val json = JSONObject(bodyString) // 获取JSON中后端定义的错误码和错误信息
                        val srvCode = json.getString(this.code)
                        val result = json.optString(data)
                        val errorMessage = json.optString(message, NetConfig.app.getString(com.drake.net.R.string.no_error_message))
                        throw NetConvertException(response,srvCode,errorMessage,result)
                    }
                }

                code in 400..499 -> throw NetConvertException(response, "$code", "请求参数错误" , bodyString)
                code >= 500 ->  throw NetConvertException(response, "$code", "服务器异常错误" , bodyString)
                else ->  throw NetConvertException(response, "$code", "Http status code not within range" , bodyString)
            }
        }
    }


    private fun <R> String.parseBody(succeed: Type): R? {
        val string = try {
            JSONObject(this).getString("data")
        } catch (e: Exception) {
            this
        }
        return JSON.parseObject(string, succeed)
    }
}